﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using Persistency.Misc;
using System.Data;
using System.Diagnostics;
using System.Windows.Forms;
using TpSettings;

namespace Persistency.Handler
{
	public class ConnectionHandler : AbstractHandler
	{

		#region Members

		private static int connectionCounter = 0;
		private static SqlConnection sqlConnection = null;
		private bool? sqlServerVersionIsSupported = null;

		private static int count = 0;

		#endregion

		#region Construction

		public ConnectionHandler() : this(false) { }

		public ConnectionHandler(bool longConnectionTimeout)
		{
			if (connectionCounter <= 0)
			{
				sqlConnection = CreateSQLConnection(longConnectionTimeout);
				try
				{
					sqlConnection.Open();
					count++;
					#region Check SQL Server Version
					if (sqlServerVersionIsSupported == null)
					{
						sqlServerVersionIsSupported = CheckIfSqlServerVersionIsSupported();
					}
					if (!sqlServerVersionIsSupported.Value)
					{
						throw new NotSupportedException("Selected version of SQL Server is not valid! SQL Server version 2005 or higher is required!");
					}
					#endregion

				}
				catch (NotSupportedException ex)
				{
					throw new PersistencyException(ex.Message);
				}
				catch (Exception)
				{
					throw new PersistencyException("Connection to Database failed!");
				}
			}
			connectionCounter++;
		}

		#endregion

		#region Properties

		public SqlConnection Connection
		{
			get
			{
#if DEBUG
				if (sqlConnection == null || sqlConnection.State != ConnectionState.Open)
				{
					//there seems to be a problem with connectionCounter!
					Debugger.Break();
				}
#endif
				return sqlConnection;
			}
		}

		#endregion

		#region Private Methods

		private bool CheckIfSqlServerVersionIsSupported()
		{
			try
			{
				string version = sqlConnection.ServerVersion;
				string[] details = version.Split(new string[] { "." }, StringSplitOptions.None);
				switch (int.Parse(details[0]))
				{
					case 8:  // SQL Server 2000
						return false;
					case 9:  // SQL Server 2005                       
					case 10: // SQL Server 2008
						return true;
					default:
						return false;
				}
			}
			catch (Exception) { }
			return false;

		}

		private SqlConnection CreateSQLConnection(bool longConnectionTimeout)
		{
			SqlConnectionStringBuilder sb = new SqlConnectionStringBuilder();
			sb.ApplicationName = Application.ProductName + " " + Application.ProductVersion;

			try
			{
                sb.ConnectionString = TpSetting.ConnectionString;
			}
			catch (Exception)
			{
				sb.ConnectionString = "";
			}
			sb.MinPoolSize = 1;

			if (longConnectionTimeout)
			{
				sb.ConnectTimeout = 600;
			}
			else
			{
				sb.ConnectTimeout = 15;
			}

			return new SqlConnection(sb.ToString());
		}

		#endregion

		#region IDisposable Interface

		protected override void Dispose(bool disposing)
		{
			if (!this.disposed)
			{
				if (disposing)
				{
					connectionCounter--;

					if (connectionCounter == 0)
					{
						sqlConnection.Close();
					}
				}
			}
			this.disposed = true;
		}

		#endregion

	}
}
